package com.genia.toolbox.projects.toolbox_basics_project.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.genia.toolbox.security.bean.Permission;
import com.genia.toolbox.security.exception.SpringSecurityExceptionsManager;

/**
 * the base controller for action needing authorization.
 */
public class AuthorizationController
    implements Controller
{

  /**
   * the {@link Controller} to forward the request when the user is authorized.
   */
  private Controller forwardController;

  /**
   * the description of the permission that the current user must have to be
   * able to execute the action.
   */
  private Permission permission;

  /**
   * the spring security messages.
   */
  private SpringSecurityExceptionsManager springSecurityExceptionsManager;



  /**
   * the main method of the Controller.
   * 
   * @param request
   *          current HTTP request
   * @param response
   *          current HTTP response
   * @return the {@link ModelAndView} to display
   * @throws Exception
   *           when an error occured
   * @see org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
      throws Exception
  {
    Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();

    if (null == currentUser) {
      throw getSpringSecurityExceptionsManager().getAccessDeniedException();
    }
    GrantedAuthority[] authorities = currentUser.getAuthorities();
    if (authorities == null) {
      throw getSpringSecurityExceptionsManager().getAccessDeniedException();
    }
    if (!ArrayUtils.contains(authorities, getPermission())) {
      throw getSpringSecurityExceptionsManager().getAccessDeniedException();
    }
    return getForwardController().handleRequest(request, response);
  }



  /**
   * getter for the forwardController property.
   * 
   * @return the forwardController
   */
  public Controller getForwardController()
  {
    return forwardController;
  }



  /**
   * setter for the forwardController property.
   * 
   * @param forwardController
   *          the forwardController to set
   */
  public void setForwardController(Controller forwardController)
  {
    this.forwardController = forwardController;
  }



  /**
   * getter for the permission property.
   * 
   * @return the permission
   */
  public Permission getPermission()
  {
    return permission;
  }



  /**
   * setter for the permission property.
   * 
   * @param permission
   *          the permission to set
   */
  public void setPermission(Permission permission)
  {
    this.permission = permission;
  }



  /**
   * getter for the springSecurityExceptionsManager property.
   * 
   * @return the springSecurityExceptionsManager
   */
  public SpringSecurityExceptionsManager getSpringSecurityExceptionsManager()
  {
    return springSecurityExceptionsManager;
  }



  /**
   * setter for the springSecurityExceptionsManager property.
   * 
   * @param springSecurityExceptionsManager
   *          the springSecurityExceptionsManager to set
   */
  public void setSpringSecurityExceptionsManager(SpringSecurityExceptionsManager springSecurityExceptionsManager)
  {
    this.springSecurityExceptionsManager = springSecurityExceptionsManager;
  }

}
